package com.ruoyi.teaching.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.teaching.domain.vo.InterviewMaseryList;
import com.ruoyi.teaching.domain.vo.RelatedInterviewVo;
import com.ruoyi.teaching.domain.vo.SelectInterviewMasery;
import com.ruoyi.teaching.es.InterviewIndex;
import com.ruoyi.teaching.util.IKAnalyzerUtils;
import io.micrometer.core.instrument.binder.BaseUnits;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import com.ruoyi.teaching.mapper.HighInterviewMapper;
import com.ruoyi.teaching.domain.HighInterview;
import com.ruoyi.teaching.service.IHighInterviewService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 高频面试题Service业务层处理
 *
 * @author sunshine
 * @date 2024-01-25
 */
@Service
@Slf4j
public class HighInterviewServiceImpl implements IHighInterviewService
{
    @Autowired
    private HighInterviewMapper highInterviewMapper;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 查询高频面试题
     *
     * @param id 高频面试题主键
     * @return 高频面试题
     */
    @Override
    public HighInterview selectHighInterviewById(Long id)
    {
        return highInterviewMapper.selectHighInterviewById(id);
    }

    /**
     * 查询高频面试题列表
     *
     * @param highInterview 高频面试题
     * @return 高频面试题
     */
    @Override
    public List<HighInterview> selectHighInterviewList(HighInterview highInterview)
    {
        return highInterviewMapper.selectHighInterviewList(highInterview);
    }

    /**
     * 新增高频面试题
     *
     * @param highInterview 高频面试题
     * @return 结果
     */
    @Override
    public int insertHighInterview(HighInterview highInterview)
    {
        highInterview.setCreateTime(DateUtils.getNowDate());
        return highInterviewMapper.insertHighInterview(highInterview);
    }

    /**
     * 修改高频面试题
     *
     * @param highInterview 高频面试题
     * @return 结果
     */
    @Override
    public int updateHighInterview(HighInterview highInterview)
    {
        highInterview.setUpdateTime(DateUtils.getNowDate());
        return highInterviewMapper.updateHighInterview(highInterview);
    }

    /**
     * 批量删除高频面试题
     *
     * @param ids 需要删除的高频面试题主键
     * @return 结果
     */
    @Override
    public int deleteHighInterviewByIds(Long[] ids)
    {
        return highInterviewMapper.deleteHighInterviewByIds(ids);
    }

    /**
     * 删除高频面试题信息
     *
     * @param id 高频面试题主键
     * @return 结果
     */
    @Override
    public int deleteHighInterviewById(Long id)
    {
        return highInterviewMapper.deleteHighInterviewById(id);
    }

    @Override
    public List<InterviewMaseryList> listInterviewMastery(SelectInterviewMasery selectInterviewMasery) {
        return highInterviewMapper.listInterviewMastery(selectInterviewMasery);
    }

    @Override
    @Transactional(readOnly = true)
    public RelatedInterviewVo queryRelatedInterview(Long cdId, String courseContent) {
        RelatedInterviewVo result = new RelatedInterviewVo();
//        根据cdid查询相关面试题
        Set<String> keywords = IKAnalyzerUtils.parseSentence(courseContent);
        if (CollectionUtils.isEmpty(keywords)){
            return result;
        }
        result.setKeywords(keywords);

        List<HighInterview> highInterviewList = highInterviewMapper.selectHighInterviewByCidId(cdId);
        if (CollectionUtils.isNotEmpty(highInterviewList)){
            result.setHighInterviewList(highInterviewList);
            result.setRelatedInterviewIdList(highInterviewList.stream().map(HighInterview::getId).collect(Collectors.toList()));
            return result;
        }

//        es
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        添加查询条件
        boolQueryBuilder.must(QueryBuilders.matchQuery("all",courseContent));
//        过滤
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        nativeSearchQueryBuilder.withPageable(PageRequest.of(0,1000));
        try {
            SearchHits<InterviewIndex> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), InterviewIndex.class);
//        将SearchHits<InterviewIndex>对象转换成面试题集合
            List<HighInterview> collect = search.getSearchHits().stream().map(sear -> {
                InterviewIndex content = sear.getContent();
                HighInterview highInterview = new HighInterview();
                BeanUtils.copyBeanProp(highInterview, content);
                return highInterview;
            }).collect(Collectors.toList());

            result.setHighInterviewList(collect);

        }catch(Exception e){
            log.error("从es查询有异常，转为在mysql查询");
            result.setHighInterviewList(highInterviewMapper.selectHighInterviewByKeyWords(keywords));
        }

            return result;
    }

    @Override
    public void exportEs() {
//        循环：每次从mysql中读取1000条数据，写入es中，退出条件
        long size = 0;
        int pageSize = 1000;
        int pageNum = 1;
        do {
            Page<HighInterview> highInterviewPage = highInterviewMapper.selectPage(new Page<HighInterview>(pageNum++, pageSize),new LambdaQueryWrapper<>());
//            size = highInterviewPage.getSize();
            List<HighInterview> records = highInterviewPage.getRecords();
            size = records.size();
//            将highInterview转为IntervireIndex
            List<InterviewIndex> collect = records.stream().map(hi -> {
                InterviewIndex build = InterviewIndex.builder().all(hi.getQuestion() + hi
                        .getAnswer()).build();
//                通过反射工具自动将HighInterview中的字段拷贝给InterviewIndex
                BeanUtils.copyBeanProp(build, hi);
                return build;
            }).collect(Collectors.toList());
            elasticsearchRestTemplate.save(collect);
        }while (size == 1000);

    }
}
